package com.chhuang.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chhuang.annotation.CurrentUser;
import com.chhuang.bean.SaUser;
import com.chhuang.bean.save.UserSo;
import com.chhuang.component.I18nMessage;
import com.chhuang.constants.MConstants;
import com.chhuang.core.bean.SaResult;
import com.chhuang.core.enums.SaCode;
import com.chhuang.core.exception.SaException;
import com.chhuang.core.valid.ValidationGroups;
import com.chhuang.model.ChUser;
import com.chhuang.service.ChUserService;
import com.chhuang.utils.digest.Md5Util;
import com.chhuang.utils.string.RegexpUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.Date;

/**
 * @ClassName PasswordController
 * @Description 用户修改密码，修改个人信息，获取个人信息
 * @Author Darren Huang
 * @Date 2022/12/22 23:43
 * @Version 1.0
 */
@Slf4j
@Validated //特别注意：@Validated要在controller上标注
@RestController
@RequestMapping("/self")
@Api(value = "SelfInfoController控制类", tags = "用户修改密码，修改个人信息")
public class SelfInfoController {

    /**
     * 获取国际化资源组件
     */
    @Resource
    private I18nMessage i18nMessage;

    /**
     * 服务对象
     */
    @Resource
    private ChUserService chUserService;

    @PostMapping("/modifyPassword")
    @ApiOperation(value = "修改用户个人密码", notes = "修改用户个人密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String")
    })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "修改用户个人密码成功")
    })
    public SaResult<Void> modifyPassword(@NotBlank(message = "{password.not_blank}")
                                             @Pattern(regexp= RegexpUtils.PASSWORD_WITH_NUM_AND_LET_SYM, message = "{password.valid_fail}")
                                                     String password,
                                         @ApiIgnore @CurrentUser SaUser saUser){
        ChUser chUser = this.chUserService.getById(saUser.getUserId());
        chUser.setPassword(Md5Util.md5(password, chUser.getUsername()));
        chUser.setModifyTime(new Date());
        if (this.chUserService.updateById(chUser)) {
            return SaResult.ok(i18nMessage.get(SaCode.SUCCESS.getCode()));
        }else {
            return SaResult.get(SaCode.MODIFY_FAIL.getCode(), i18nMessage.get(SaCode.MODIFY_FAIL.getCode()));
        }
    }

    /**
     * 修改用户个人信息
     * @param userSo
     * @param saUser
     * @return
     */
    @PostMapping("/modifySelfinfo")
    @ApiOperation(value = "修改用户个人信息", notes = "修改用户个人信息")
    @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "修改用户个人信息成功")
    })
    public SaResult<SaUser> modifySelfinfo(@Validated(ValidationGroups.ModifyGroup.class) @RequestBody UserSo userSo,
                                           @ApiIgnore @CurrentUser SaUser saUser){
        userSo.setUserId(saUser.getUserId());
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getUsername, userSo.getUsername()))){
            throw new SaException(SaCode.REGEDIT_USERNAME_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getPhone, userSo.getPhone()))){
            throw new SaException(SaCode.REGEDIT_PHONE_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getEmail, userSo.getEmail()))){
            throw new SaException(SaCode.REGEDIT_EMAIL_ALREADY_EXISTS);
        }

        ChUser user = new ChUser();
        BeanUtil.copyProperties(userSo, user);
        user.setPassword(null);
        user.setModifyTime(new Date());

        if (this.chUserService.updateById(user)) {
            BeanUtil.copyProperties(user, saUser);
            StpUtil.getSession().set(MConstants.SESSION_USER_KEY, saUser);
            return SaResult.data(saUser);
        }else {
            return SaResult.get(SaCode.MODIFY_FAIL.getCode(), i18nMessage.get(SaCode.MODIFY_FAIL.getCode()));
        }
    }
}
